﻿using Kimd.Common;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WorkStation.Common;

namespace WorkStation.Logic
{
    public class PutScanNGLogic : FlowBase
    {
        private bool _isFront;
        private Tray _scanNGTray;
        private Axis _z1;
        private Axis _y1;
        private Axis _r1;
        private Axis _x1;
        private Axis _ngAxis;
        private List<Cylinder> _feedCylinders1;
        private List<Cylinder> _feedVacs1;
        private List<Cylinder> _feedRevVacs1;

        private List<Cylinder> _bufferVacs1;
        private List<Sensor> _feedVacSenses1;

        private Axis _z2;
        private Axis _y2;
        private Axis _r2;
        private Axis _x2;
        private List<Cylinder> _feedCylinders2;
        private List<Cylinder> _feedVacs2;
        private List<Cylinder> _feedRevVacs2;

        private List<Cylinder> _bufferVacs2;
        private List<Sensor> _feedVacSenses2;
        public PutScanNGLogic(string flowName, FlowManager flowmanager, bool isFront)
            : base(flowName, flowmanager)
        {
            this._isFront = isFront;

            if (_isFront)
            {
                _z1 = MachineResource.Instance.MachineAxis[$"Arm1Z轴"];
                _y1 = MachineResource.Instance.MachineAxis[$"Arm1Y轴"];
                _r1 = MachineResource.Instance.MachineAxis[$"Arm1U轴"];
                _x1 = MachineResource.Instance.MachineAxis[$"测试移载线1左轴"];

                this._feedCylinders1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1上下气缸1"],
                    MachineResource.Instance.MachineCylinder[$"Arm1上下气缸2"],
                };
                this._feedVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1吸真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm1吸真空2"],
                };
                this._feedRevVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm1破真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm1破真空2"],
                };
                this._bufferVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸1"],
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸2"],
                };
                this._feedVacSenses1 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm1吸真空1达到"],
                    MachineResource.Instance.MachineSensor[$"Arm1吸真空2达到"],
                };

                _z2 = MachineResource.Instance.MachineAxis[$"Arm2Z轴"];
                _y2 = MachineResource.Instance.MachineAxis[$"Arm2Y轴"];
                _r2 = MachineResource.Instance.MachineAxis[$"Arm2U轴"];
                _x2 = MachineResource.Instance.MachineAxis[$"测试移载线1右轴"];
                this._feedCylinders2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2上下气缸1"],
                    MachineResource.Instance.MachineCylinder[$"Arm2上下气缸2"],
                };
                this._feedVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2吸真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm2吸真空2"],
                };
                this._feedRevVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm2破真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm2破真空2"],
                };
                this._bufferVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸3"],
                    MachineResource.Instance.MachineCylinder["精定位1OKBuffer位真空吸4"],
                };
                this._feedVacSenses2 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm2吸真空1达到"],
                    MachineResource.Instance.MachineSensor[$"Arm2吸真空2达到"],
                };

                _ngAxis = MachineResource.Instance.MachineAxis["精定位1NG轴"];

                RegisterDirectSignal($"Arm1放扫码NG完成");
                RegisterDirectSignal($"Arm2放扫码NG完成");
            }
            else
            {
                _z1 = MachineResource.Instance.MachineAxis[$"Arm3Z轴"];
                _y1 = MachineResource.Instance.MachineAxis[$"Arm3Y轴"];
                _r1 = MachineResource.Instance.MachineAxis[$"Arm3U轴"];
                _x1 = MachineResource.Instance.MachineAxis[$"测试移载线2左轴"];
                this._feedCylinders1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3上下气缸3"],
                    MachineResource.Instance.MachineCylinder[$"Arm3上下气缸4"],
                };
                this._feedVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3吸真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm3吸真空4"],
                };
                this._feedRevVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm3破真空3"],
                    MachineResource.Instance.MachineCylinder[$"Arm3破真空4"],
                };
                this._bufferVacs1 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸1"],
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸2"],
                };
                this._feedVacSenses1 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm3吸真空3达到"],
                    MachineResource.Instance.MachineSensor[$"Arm3吸真空4达到"],
                };

                _z2 = MachineResource.Instance.MachineAxis[$"Arm4Z轴"];
                _y2 = MachineResource.Instance.MachineAxis[$"Arm4Y轴"];
                _r2 = MachineResource.Instance.MachineAxis[$"Arm4U轴"];
                _x2 = MachineResource.Instance.MachineAxis[$"测试移载线2右轴"];
                this._feedCylinders2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4上下气缸1"],
                    MachineResource.Instance.MachineCylinder[$"Arm4上下气缸2"],
                };
                this._feedVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4吸真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm4吸真空2"],
                };
                this._feedRevVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder[$"Arm4破真空1"],
                    MachineResource.Instance.MachineCylinder[$"Arm4破真空2"],
                };
                this._bufferVacs2 = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸3"],
                    MachineResource.Instance.MachineCylinder["精定位2OKBuffer位真空吸4"],
                };
                this._feedVacSenses2 = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor[$"Arm4吸真空1达到"],
                    MachineResource.Instance.MachineSensor[$"Arm4吸真空2达到"],
                };

                _ngAxis = MachineResource.Instance.MachineAxis["精定位2NG轴"];

                RegisterDirectSignal($"Arm3放扫码NG完成");
                RegisterDirectSignal($"Arm4放扫码NG完成");
            }

            _scanNGTray = new Tray(2, 6);
        }

        public override void Calibrate()
        {
            base.Calibrate();
        }

        public override void Home()
        {
            _scanNGTray.Helper.NewEmptyTray();
        }

        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }

        public override void Method()
        {
            if (!CheckFlowCondition()) return;
            if (GlobalVariable.IsSpotChecking)
                return;

            Tray feedTray1 = null;
            Tray feedTray2 = null;

            if (_isFront)
            {
                WaitForSignal("Arm1模组", "Arm1放扫码NG请求");
                if (!CheckFlowCondition()) return;
                WaitForSignal("Arm2模组", "Arm2放扫码NG请求");
                if (!CheckFlowCondition()) return;

                feedTray1 = (_flowManager.SelectFlow("Arm1模组") as TransferLogic).GetFeedTray();
                feedTray2 = (_flowManager.SelectFlow("Arm2模组") as TransferLogic).GetFeedTray();
            }
            else
            {
                WaitForSignal("Arm3模组", "Arm3放扫码NG请求");
                if (!CheckFlowCondition()) return;
                WaitForSignal("Arm4模组", "Arm4放扫码NG请求");
                if (!CheckFlowCondition()) return;

                feedTray1 = (_flowManager.SelectFlow("Arm3模组") as TransferLogic).GetFeedTray();
                feedTray2 = (_flowManager.SelectFlow("Arm4模组") as TransferLogic).GetFeedTray();
            }

            if (feedTray1.Helper.Any(c => c.Status == CellStatus.HasProduct && c.SN == null))
            {

            }
            if (feedTray2.Helper.Any(c => c.Status == CellStatus.HasProduct && c.SN == null))
            {

            }
            bool hasNg = PutScanP(feedTray1, feedTray2);
            #region 扫码NG后进行测试Arm1，3需要避让
            if ((feedTray1.Helper.GetCell(0).Status == CellStatus.HasProduct
                || feedTray1.Helper.GetCell(1).Status == CellStatus.HasProduct) &&hasNg)
            {
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"待机位"]);
                pos.Add(_ngAxis.MotionPosition[$"安全位"]);
                AxisMoveSimultaneously(new List<Axis>() { _x1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
            }
            else
            {
                SingleAxisMove2Point(_ngAxis, "安全位");
                if (!CheckFlowCondition()) return;
            }
            #endregion

            if (_isFront)
            {
                SetSignal($"Arm1放扫码NG完成");
                SetSignal($"Arm2放扫码NG完成");
            }
            else
            {
                SetSignal($"Arm3放扫码NG完成");
                SetSignal($"Arm4放扫码NG完成");
            }
        }
        public override void InSingleRunMode()
        {
            if (GlobalVariable.OnSingleRunPause != null)
                GlobalVariable.OnSingleRunPause();
        }
        public override void OnStop()
        {
            base.OnStop();
        }

        public bool PutScanP(Tray feedTray1, Tray feedTray2)
        {
            bool hasNG = false;
            if (feedTray1.Helper.Any(c => c.Status == CellStatus.HasProduct && c.SN.Contains("NG")) ||
                   feedTray2.Helper.Any(c => c.Status == CellStatus.HasProduct && c.SN.Contains("NG")))
            {
                checkTrayFullAndReplace(_scanNGTray, "扫码NG Tray已满，请更换!", _isFront ? "前Arm模组" : "后Arm模组", GlobalVariable.IsDryRun);
                if (!CheckFlowCondition()) return hasNG;
                for (int i = 0; i < 2; i++)
                {
                    if (feedTray1.Helper.GetCell(i).Status == CellStatus.HasProduct &&
                        feedTray1.Helper.GetCell(i).SN.Contains("NG"))
                    {

                        putScanNGProduct(_scanNGTray, 0, $"吸嘴{i + 1}", i, feedTray1);
                        if (!CheckFlowCondition()) return hasNG;
                        lock (GlobalVariable.FrontBackOutputDataLock)
                        {
                            GlobalVariable.CurrentMachineData.TotalOutputCount += 1;
                        }
                        GlobalVariable.SaveMachineData(GlobalVariable.CurrentMachineData);
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalOutputCount.ToString(), this.Description, 0, "Output"));
                        checkTrayFullAndReplace(_scanNGTray, $"扫码NG Tray已满，请更换!", _isFront ? "前Arm模组" : "后Arm模组", GlobalVariable.IsDryRun);
                        hasNG = true;
                    }
                }
                for (int i = 0; i < 2; i++)
                {
                    if (feedTray2.Helper.GetCell(i).Status == CellStatus.HasProduct &&
                        feedTray2.Helper.GetCell(i).SN.Contains("NG"))
                    {
                        putScanNGProduct(_scanNGTray, 1, $"吸嘴{i + 1}", i, feedTray2);
                        if (!CheckFlowCondition()) return hasNG;
                        lock (GlobalVariable.FrontBackOutputDataLock)
                        {
                            GlobalVariable.CurrentMachineData.TotalOutputCount += 1;
                        }
                        GlobalVariable.SaveMachineData(GlobalVariable.CurrentMachineData);
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalOutputCount.ToString(), this.Description, 0, "Output"));
                        checkTrayFullAndReplace(_scanNGTray, $"扫码NG Tray已满，请更换!", _isFront ? "前Arm模组" : "后Arm模组", GlobalVariable.IsDryRun);
                    }
                }
            }
            return hasNG;
        }


        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }
        public Tray GetScanNGTray()
        {
            return _scanNGTray;
        }
        public void putScanNGProduct(Tray scanNGTray, int headerIndex, string nozzleName, int nozzleIndex, Tray feedTray)
        {
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"放扫码NG品 headerIndex:{headerIndex} nozzleName:{nozzleName} nozzleIndex:{nozzleIndex} ", this.Description, 0, this.Description));
            AxisMoveSimultaneously(new List<Axis>() { _z1, _z2 }, "待机位");
            if (!CheckFlowCondition()) return;
            if (headerIndex == 0)
            {
                int putIndex = scanNGTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                List<double> pos = new List<double>();
                pos.Add(_x1.MotionPosition[$"扫码NG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x2.MotionPosition["Arm右避让位"]);
                pos.Add(_r1.MotionPosition[$"扫码NG矩阵Arm左{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}扫码NG左"]);
                SingleAxisMove2Point(_y1, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x1, _x2, _r1, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y1, $"扫码NG矩阵Arm左{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z1,
                                    new List<Cylinder>() { _feedCylinders1[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _feedRevVacs1[nozzleIndex] },
                                    new List<Cylinder>() { _bufferVacs1[nozzleIndex] },
                                    $"扫码NG矩阵Arm左{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    300);
                if (!CheckFlowCondition()) return;
                //交换料状态
                scanNGTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                scanNGTray.Helper.SetCellBarcode(putIndex, feedTray.Helper.GetCell(nozzleIndex).SN);
                scanNGTray.Helper.SetCellResult(putIndex, feedTray.Helper.GetCell(nozzleIndex).Result);
                scanNGTray.Helper.SetCellTesters(putIndex, feedTray.Helper.GetCell(nozzleIndex).TestedTesters);

                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                feedTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
            else if (headerIndex == 1)
            {
                int putIndex = scanNGTray.Helper.GetFirstIndex(CellStatus.NoProduct);
                List<double> pos = new List<double>();
                pos.Add(_x2.MotionPosition[$"扫码NG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_x1.MotionPosition["Arm左避让位"]);
                pos.Add(_r2.MotionPosition[$"扫码NG矩阵Arm右{nozzleName}-{putIndex}-{0}"]);
                pos.Add(_ngAxis.MotionPosition[$"{nozzleName}扫码NG右"]);
                SingleAxisMove2Point(_y2, "旋转位");
                if (!CheckFlowCondition()) return;
                AxisMoveSimultaneously(new List<Axis>() { _x2, _x1, _r2, _ngAxis }, pos);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_y2, $"扫码NG矩阵Arm右{nozzleName}-{putIndex}-{0}");
                if (!CheckFlowCondition()) return;
                NozzlePutProductExt(_z2,
                                    new List<Cylinder>() { _feedCylinders2[nozzleIndex] },
                                    new List<Cylinder>() { _feedVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _feedRevVacs2[nozzleIndex] },
                                    new List<Cylinder>() { _bufferVacs2[nozzleIndex] },
                                    $"扫码NG矩阵Arm右{nozzleName}-{putIndex}-{0}",
                                    "待机位",
                                    zRelPos: SystemConfig.Instance.TestParam.ArmZHValuePutInNG,
                                    zRelSpeed: SystemConfig.Instance.TestParam.ArmZHValueSpeedPutInNG,
                                    5000,
                                    300);
                if (!CheckFlowCondition()) return;
                //交换料状态
                scanNGTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                scanNGTray.Helper.SetCellBarcode(putIndex, feedTray.Helper.GetCell(nozzleIndex).SN);
                scanNGTray.Helper.SetCellResult(putIndex, feedTray.Helper.GetCell(nozzleIndex).Result);
                scanNGTray.Helper.SetCellTesters(putIndex, feedTray.Helper.GetCell(nozzleIndex).TestedTesters);

                feedTray.Helper.SetCellStatus(nozzleIndex, CellStatus.NoProduct);
                feedTray.Helper.SetCellBarcode(nozzleIndex, string.Empty);
                feedTray.Helper.SetCellResult(nozzleIndex, TestResult.NoTest);
            }
        }
    }
}
